<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>The source code</title>
  <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
  <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
  <style type="text/css">
    .highlight { display: block; background-color: #ddd; }
  </style>
  <script type="text/javascript">
    function highlight() {
      document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
    }
  </script>
</head>
<body onload="prettyPrint(); highlight();">
  <pre class="prettyprint lang-js">var _core = require(&quot;../core&quot;);

var createElement = _core.createElement;

var dataUtil = require(&quot;../../core/utils/data_structure_util&quot;);

var Path = require(&quot;../../graphic/Path&quot;);

var QImage = require(&quot;../../graphic/Image&quot;);

var QText = require(&quot;../../graphic/Text&quot;);

var _graphic = require(&quot;../graphic&quot;);

var svgPath = _graphic.path;
var svgImage = _graphic.image;
var svgText = _graphic.text;

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(&quot;Cannot call a class as a function&quot;); } }

function _defineProperties(target, props) { for (var i = 0; i &lt; props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (&quot;value&quot; in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

<span id='qrenderer-svg-helper-Definable'>/**
</span> * @class qrenderer.svg.helper.Definable
 * 
 * Manages elements that can be defined in &lt;defs&gt; in SVG,
 *       e.g., gradients, clip path, etc.
 * @author Zhang Wenli
 * @docauthor 大漠穷秋 damoqiongqiu@126.com
 */
var MARK_UNUSED = &#39;0&#39;;
var MARK_USED = &#39;1&#39;;

var Definable =
/*#__PURE__*/
function () {
<span id='qrenderer-svg-helper-Definable-method-constructor'>  /**
</span>   * @method constructor Definable
   * 
   * Manages elements that can be defined in &lt;defs&gt; in SVG,
   * e.g., gradients, clip path, etc.
   *
   * @param {Number}          qrId      qrenderer instance id
   * @param {SVGElement}      svgRoot   root of SVG document
   * @param {String|String[]} tagNames  possible tag names
   * @param {String}          markLabel label name to make if the element
   *                                    is used
   */
  function Definable(qrId, svgRoot, tagNames, markLabel, domName) {
    _classCallCheck(this, Definable);

    this._qrId = qrId;
    this._svgRoot = svgRoot;
    this._tagNames = typeof tagNames === &#39;string&#39; ? [tagNames] : tagNames;
    this._markLabel = markLabel;
    this._domName = domName || &#39;_dom&#39;;
    this.nextId = 0;
    this.createElement = createElement;
  }
<span id='qrenderer-svg-helper-Definable-method-getDefs'>  /**
</span>   * @method getDefs
   * 
   * Get the &lt;defs&gt; tag for svgRoot; optionally creates one if not exists.
   *
   * @param {Boolean} isForceCreating if need to create when not exists
   * @return {SVGDefsElement} SVG &lt;defs&gt; element, null if it doesn&#39;t exist and isForceCreating is false
   */


  _createClass(Definable, [{
    key: &quot;getDefs&quot;,
    value: function getDefs(isForceCreating) {
      var svgRoot = this._svgRoot;

      var defs = this._svgRoot.getElementsByTagName(&#39;defs&#39;);

      if (defs.length === 0) {
        // Not exist
        if (isForceCreating) {
          defs = svgRoot.insertBefore(this.createElement(&#39;defs&#39;), // Create new tag
          svgRoot.firstChild // Insert in the front of svg
          );

          if (!defs.contains) {
            // IE doesn&#39;t support contains method
            defs.contains = function (el) {
              var children = defs.children;

              if (!children) {
                return false;
              }

              for (var i = children.length - 1; i &gt;= 0; --i) {
                if (children[i] === el) {
                  return true;
                }
              }

              return false;
            };
          }

          return defs;
        } else {
          return null;
        }
      } else {
        return defs[0];
      }
    }
<span id='qrenderer-svg-helper-Definable-method-update'>    /**
</span>     * @method update
     * 
     * Update DOM element if necessary.
     *
     * @param {Object|String} element style element. e.g., for gradient, it may be &#39;#ccc&#39; or {type: &#39;linear&#39;, ...}
     * @param {Function|undefined} onUpdate update callback
     */

  }, {
    key: &quot;update&quot;,
    value: function update(element, onUpdate) {
      if (!element) {
        return;
      }

      var defs = this.getDefs(false);

      if (element[this._domName] &amp;&amp; defs.contains(element[this._domName])) {
        // Update DOM
        if (typeof onUpdate === &#39;function&#39;) {
          onUpdate(element);
        }
      } else {
        // No previous dom, create new
        var dom = this.add(element);

        if (dom) {
          element[this._domName] = dom;
        }
      }
    }
<span id='qrenderer-svg-helper-Definable-method-addDom'>    /**
</span>     * @method addDom
     * 
     * Add gradient dom to defs
     *
     * @param {SVGElement} dom DOM to be added to &lt;defs&gt;
     */

  }, {
    key: &quot;addDom&quot;,
    value: function addDom(dom) {
      var defs = this.getDefs(true);
      defs.appendChild(dom);
    }
<span id='qrenderer-svg-helper-Definable-method-removeDom'>    /**
</span>     * @method removeDom
     * 
     * Remove DOM of a given element.
     *
     * @param {SVGElement} element element to remove dom
     */

  }, {
    key: &quot;removeDom&quot;,
    value: function removeDom(element) {
      var defs = this.getDefs(false);

      if (defs &amp;&amp; element[this._domName]) {
        defs.removeChild(element[this._domName]);
        element[this._domName] = null;
      }
    }
<span id='qrenderer-svg-helper-Definable-method-getDoms'>    /**
</span>     * @method getDoms
     * 
     * Get DOMs of this element.
     *
     * @return {HTMLDomElement} doms of this defineable elements in &lt;defs&gt;
     */

  }, {
    key: &quot;getDoms&quot;,
    value: function getDoms() {
      var defs = this.getDefs(false);

      if (!defs) {
        // No dom when defs is not defined
        return [];
      }

      var doms = [];
      dataUtil.each(this._tagNames, function (tagName) {
        var tags = defs.getElementsByTagName(tagName); // Note that tags is HTMLCollection, which is array-like
        // rather than real array.
        // So `doms.concat(tags)` add tags as one object.

        doms = doms.concat([].slice.call(tags));
      });
      return doms;
    }
<span id='qrenderer-svg-helper-Definable-method-markAllUnused'>    /**
</span>     * @method markAllUnused
     * 
     * Mark DOMs to be unused before painting, and clear unused ones at the end
     * of the painting.
     */

  }, {
    key: &quot;markAllUnused&quot;,
    value: function markAllUnused() {
      var doms = this.getDoms();
      var that = this;
      dataUtil.each(doms, function (dom) {
        dom[that._markLabel] = MARK_UNUSED;
      });
    }
<span id='qrenderer-svg-helper-Definable-method-markUsed'>    /**
</span>     * @method markUsed
     * 
     * Mark a single DOM to be used.
     *
     * @param {SVGElement} dom DOM to mark
     */

  }, {
    key: &quot;markUsed&quot;,
    value: function markUsed(dom) {
      if (dom) {
        dom[this._markLabel] = MARK_USED;
      }
    }
<span id='qrenderer-svg-helper-Definable-method-removeUnused'>    /**
</span>     * @method removeUnused
     * 
     * Remove unused DOMs defined in &lt;defs&gt;
     */

  }, {
    key: &quot;removeUnused&quot;,
    value: function removeUnused() {
      var defs = this.getDefs(false);

      if (!defs) {
        // Nothing to remove
        return;
      }

      var doms = this.getDoms();
      var that = this;
      dataUtil.each(doms, function (dom) {
        if (dom[that._markLabel] !== MARK_USED) {
          // Remove gradient
          defs.removeChild(dom);
        }
      });
    }
<span id='qrenderer-svg-helper-Definable-method-getSvgProxy'>    /**
</span>     * @method getSvgProxy
     * 
     * Get SVG proxy.
     *
     * @param {Displayable} displayable displayable element
     * @return {Path|Image|Text} svg proxy of given element
     */

  }, {
    key: &quot;getSvgProxy&quot;,
    value: function getSvgProxy(displayable) {
      if (displayable instanceof Path) {
        return svgPath;
      } else if (displayable instanceof QImage) {
        return svgImage;
      } else if (displayable instanceof QText) {
        return svgText;
      } else {
        return svgPath;
      }
    }
<span id='qrenderer-svg-helper-Definable-method-getTextSvgElement'>    /**
</span>     * @method getTextSvgElement
     * 
     * Get text SVG element.
     *
     * @param {Displayable} displayable displayable element
     * @return {SVGElement} SVG element of text
     */

  }, {
    key: &quot;getTextSvgElement&quot;,
    value: function getTextSvgElement(displayable) {
      return displayable.__textSvgEl;
    }
<span id='qrenderer-svg-helper-Definable-method-getSvgElement'>    /**
</span>     * @method getSvgElement
     * 
     * Get SVG element.
     *
     * @param {Displayable} displayable displayable element
     * @return {SVGElement} SVG element
     */

  }, {
    key: &quot;getSvgElement&quot;,
    value: function getSvgElement(displayable) {
      return displayable.__svgEl;
    }
  }]);

  return Definable;
}();

var _default = Definable;
module.exports = _default;</pre>
</body>
</html>
